const gui = new dat.GUI();
const PI = Math.PI;

const params = {
    axisShow: true,

    // scale: 1.1, // 放大比例

    // // 曲线：起始半径、起始角度
    // angleR0: 0.3,
    // angle0: 0,

    // // 参考曲线点：弧度点增量、绘制点数上限
    guideShow: true,
    // lineAngleDelta: Math.PI / 2 / 100,
    // linePointsLimit: 2121,

    // // 圆：起始半径、开始的圆距0点距离、每个圆的间隔的点数
    // circleR0: 6,
    // drawCircleStartR: 34.3,
    // drawCircleEveryN: 100,

    // // rDelta: 0.001,    // 半径增量，单位：像素

    // limit: 10000, // 绘制点数上限

    // angleDeltaDegrees: 1.8, // 弧度增量，单位：角度
    // angleDeltaSpeed: parseFloat((0.01 * Math.PI).toFixed(2)) // 弧度增量，单位：弧度，由angleDeltaDegrees自动维护

    r_0: 20,   // 起始半径
    x: 1.2,    // 放大倍率
    roundScale: 1.1,    // 转一圈的放大倍率
    roundTime: 3, // 一圈时间
    theta_speed: 45, // 角速度
    // t: 0,      // 时间

    t_limit: 50, // 螺旋线的点数上限

    circle_between_theta: 60, // 每个圆，间隔角度
    circle_r_0: 4.5, // 圆的起始半径
    circle_limit: 50, // 圆的点数上限
};

// 添加模拟分割线的方法
function addDivider(gui, label = '------') {
    gui.add({Dummy: function() {}}, 'Dummy').name(label).domElement.parentNode.parentNode.style.pointerEvents = 'none';
}

gui.add(params, 'axisShow').name('显示坐标系');

// 添加分割线
addDivider(gui);


gui.add(params, 'guideShow').name('显示参考线');

gui.add(params, 'r_0', 0.1, 10).name('起始半径').step(0.01);
gui.add(params, 'x', 0.1, 2).name('t放大倍率').step(0.01);
gui.add(params, 'roundScale', 0.1, 2).name('转一圈放大倍率').step(0.01);
gui.add(params, 'roundTime', 1, 10).name('一圈时间').step(0.1);
gui.add(params, 'theta_speed', 0, 360).name('角速度').step(0.1);

// gui.add(params, 't', 0, 100).name('时间').step(0.1);

// 添加分割线
addDivider(gui);

gui.add(params, 't_limit', 10, 200).name('螺旋线-点上线').step(1);

gui.add(params, 'circle_between_theta', 1, 360).name('圆间隔角度').step(0.1);
gui.add(params, 'circle_r_0', 1, 30).name('圆起始半径').step(0.1);


// 半径随时间的变化
function rx(currentTime) {
    // 圈数
    const round = currentTime / params.roundTime;

    // 半径
    return params.r_0 * round * params.roundScale;
}

// 半径随t的变化
function r(t) {
    return params.r_0 * Math.pow(params.x, t);
}

// 弧度随t的变化
function phi(t) {
    // 角速度 * PI / 180 => 弧度速度
    return params.theta_speed * PI / 180 * t;
}
// x, y坐标随t的变化
function x(t) {
    return r(t) * Math.cos(phi(t));
}
function y(t) {
    return r(t) * Math.sin(phi(t));
}


// t随当前角度theta的变化
function f_t(theta) {
    return theta / params.theta_speed;
}

// 螺旋线的位置坐标xy随角度theta的变化
function pos(theta) {
    const t = f_t(theta);
    const x =  r(t) * Math.cos(phi(t));
    const y = r(t) * Math.sin(phi(t));
    return {x, y};
}

// 圆的半径随t的变化
function circle_r(t) {
    return params.circle_r_0 * Math.pow(params.x, t);
}



// gui.add(params, 'scale', 0.1, 2).name('放大比例').step(0.01);

// var group1 = gui.addFolder('圆弧参数');
// group1.add(params, 'angleR0', 0.1, 1).name('起始半径').step(0.01);
// group1.add(params, 'angle0', 0, Math.PI * 2).name('起始角度').step(0.01);
// group1.add(params, 'lineShow').name('显示参考线');
// group1.add(params, 'lineAngleDelta', 0.01, 0.1).step(0.001).name('参考线-角度增量');
// group1.add(params, 'linePointsLimit', 1000, 5000).step(1).name('参考线-点数上限');

// var group2 = gui.addFolder('圆点参数');
// group2.add(params, 'circleR0', 2, 10).name('起始半径').step(0.1);
// group2.add(params, 'drawCircleStartR', 30, 1000).name('开始绘制的范围半径').step(0.1);
// group2.add(params, 'drawCircleEveryN', 10, 1000).name('每个圆的间隔的点数').step(1);


// group1.open();
// group2.open();


// 全局用的变量
var c = undefined;
var ctx = undefined;

// 方法定义 ========================================

// 设置画布宽高
function setCanvasSize() {
    var maxWH = Math.max(document.documentElement.clientWidth, document.documentElement.clientHeight);
    var minWH = Math.min(document.documentElement.clientWidth, document.documentElement.clientHeight);

    // 使用 document.documentElement.clientWidth 和 .clientHeight
    // c.width = maxWH;
    // c.height = maxWH;
    c.width = minWH;
    c.height = minWH;
    
    // 屏幕中心设为原点
    ctx.translate(c.width / 2, c.height / 2);
}

// 清空画布
function clearCanvas() {
    const ex = 10;
    // 清空画布
    ctx.clearRect(-c.width / 2 - ex, -c.height / 2 - ex, c.width + ex, c.height + ex);
}

// 绘制坐标轴
function drawAxis() {
    // 绘制原点（红色、7px、圆形、填充）
    ctx.fillStyle = "red";
    ctx.beginPath();
    ctx.arc(0, 0, 3, 0, Math.PI * 2);
    ctx.fill();
    ctx.closePath();
    

    ctx.beginPath();
    ctx.moveTo(-c.width / 2, 0);
    ctx.lineTo(c.width / 2, 0);
    ctx.moveTo(0, -c.height / 2);
    ctx.lineTo(0, c.height / 2);
    ctx.stroke();

    // 绘制坐标轴上的刻度
    for (var i = 0; i < c.width / 2; i += 20) {
        ctx.beginPath();
        ctx.moveTo(i, -5);
        ctx.lineTo(i, 5);
        ctx.stroke();
        
        ctx.beginPath();
        ctx.moveTo(-i, -5);
        ctx.lineTo(-i, 5);
        ctx.stroke();
    }
    for (var i = 0; i < c.height / 2; i += 20) {
        ctx.beginPath();
        ctx.moveTo(-5, i);
        ctx.lineTo(5, i);
        ctx.stroke();

        ctx.beginPath();
        ctx.moveTo(-5, -i);
        ctx.lineTo(5, -i);
        ctx.stroke();
    }
    ctx.closePath();
}

// 判断当前x, y是否在画布内
function isInCanvas(x, y) {
    return x >= -c.width / 2 && x <= c.width / 2 && y >= -c.height / 2 && y <= c.height / 2;
}

// 绘制参考用的螺旋线
function drawGuideLine() {
    // 绘制多个原点 - 连成线
    var t_n = 0;
    var t_step = 0.001;
    var t_limit = params.t_limit    // 线的点数上限;
    while(t_n < t_limit) {
        ctx.beginPath();
        ctx.arc(x(t_n), y(t_n), 1, 0, Math.PI * 2);
        ctx.fill();
        ctx.closePath();
        t_n += t_step;
    }
}

function drawSingleCircle(x, y, r) {
    ctx.beginPath();
    ctx.arc(x, y, r, 0, Math.PI * 2);
    ctx.fill();
    ctx.closePath();
}

// 绘制圆
function drawCircle() {
    let i = 0;
    let limit = params.circle_limit;

    while(i < limit) {
        const theta = i * params.circle_between_theta;
        const {x, y} = pos(theta);
        const r = circle_r(f_t(theta));

        drawSingleCircle(x, y, r);

        i++;
    }
}

// 绘制内容
function drawContent() {
    if (params.guideShow) {
        drawGuideLine();
    }

    // 绘制圆点
    drawCircle();

    // 绘制原点
    drawSingleCircle(0, 0, 3);
}

// 每次绘制的方法
function draw() {
    clearCanvas();

    if (params.axisShow) {
        drawAxis();
    }
    
    drawContent();
    console.log("draw");
}

// 初始化，只运行依次的代码
function init() {
    c = document.body.querySelector("#c");
    ctx = c.getContext("2d");

    setCanvasSize();

    // 窗口大小调整时，重新设置宽高，并重新绘制
    window.onresize = function() {
        setCanvasSize();
        draw();
    }

    // 绘制一帧
    draw();
}

// 启动 ========================================

init();


var changeRedraw = function(controller) {
    controller.onChange(function() {
        draw();
    });
}
// GUI变量监听：当受控变量发生变化时，重新绘制
gui.__controllers.forEach(changeRedraw);
console.log("gui.__folders >>>", gui.__folders);
Array.from(Object.keys(gui.__folders)).forEach(function(folderName) {
    gui.__folders[folderName].__controllers.forEach(changeRedraw);
});


function getRandomColor() {
    return '#' + Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, '0') + '3f';
}

// 测试动画 =====================================
function startAnime() {
    // 先从canvas截图，放到页面上，然后一边以scale的倍率放大，一边旋转
    console.log("startAnime");

    // 旋转一周的时间
    var turnARoundTime = 3;
    var turn2RoundTime = 6;

    // 旋转n周后消失
    var disapearAfterTrunRoundCount = 2;

    // 启动新实例间隔时间
    var newAnimeInterval = 3;

    // 旋转2周的放大倍率 = 倍率 
    var endScale = Math.pow(params.x, turn2RoundTime);

    console.log("转两圈的放大倍率：", endScale);

    var r0 = 10;
    




    // 获取canvas的DataURL
    var dataURL = c.toDataURL();
    var ctn = document.body.querySelector('.ctn');

    function imgGo() {
        console.log("imgGO!!!");

        // 创建一个div
        var div = document.createElement('div');
        div.classList.add('canvas-div');
        div.style.backgroundColor = getRandomColor();


        // 创建一个新的Image对象
        var img = new Image();
        // 设置其来源为我们刚刚获取的DataURL
        img.src = dataURL;
        img.classList.add('canvas-img');
        img.style.transition = "";

        c.style.display = 'none';

        div.appendChild(img);
        ctn.appendChild(div);

        // 应用动画
        // img.style.setProperty('--endScale', endScale.toString());
        /* img.style.setProperty('--endScale', endScale.toString());
        img.style.animation = `rotateAndScale ${6}s linear infinite`;
        img.style.opacity = "0.1"; */

        // div负责旋转 两周
        div.style.animation = `onlyRotate ${turn2RoundTime}s linear infinite`;

        // img负责放大
        img.style.setProperty('--endScale', endScale.toString());
        img.style.animation = `onlyScale ${turn2RoundTime}s linear infinite`;


        // if (x) {
        //     img.style.animation = `rotateAndScale1 ${turnARoundTime}s linear infinite`;
        // }
        // else {
        //     img.style.animation = `rotateAndScale ${turnARoundTime}s linear infinite`;
        // }

        // 旋转2周后，干掉自己
        setTimeout(function() {
            ctn.removeChild(div);
            
            console.log("rm!!!");
        }, turn2RoundTime * 1000);
    }

    function repeatFunc() {
        imgGo();

        // setTimeout(function() {
        //     repeatFunc();
        // }, newAnimeInterval * 1000);
    }
    repeatFunc();

    // TODEL: 测试用代码
    // imgGo();
    // setTimeout(function(){
    //     imgGo(1);
    // }, 1000);

    ctn.style.transform = "translate(-50%, -50%)";
}

gui.add({
    startAnime
}, 'startAnime').name("开始动画")
